home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/python
-
- # ubuntuone-client-applet - Tray icon applet for managing Ubuntu One
- #
- # Author: Rodney Dawes <rodney.dawes@canonical.com>
- #
- # Copyright 2009 Canonical Ltd.
- #
- # This program is free software: you can redistribute it and/or modify it
- # under the terms of the GNU General Public License version 3, as published
- # by the Free Software Foundation.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranties of
- # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
- # PURPOSE. See the GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program. If not, see <http://www.gnu.org/licenses/>.
-
- from __future__ import with_statement
-
- import pygtk
- pygtk.require('2.0')
- import gobject
- import gtk
- import os
- import gettext
- from ubuntuone import clientdefs
-
- import dbus.service
- from ConfigParser import ConfigParser
- from dbus.exceptions import DBusException
- from dbus.mainloop.glib import DBusGMainLoop
- from xdg.BaseDirectory import xdg_config_home
-
- DBusGMainLoop(set_as_default=True)
-
- _ = gettext.gettext
-
- APPLET_IFACE_NAME = "com.ubuntuone.ClientApplet"
- APPLET_IFACE_CONFIG_NAME = APPLET_IFACE_NAME + ".Config"
-
- DBUS_IFACE_NAME = "com.ubuntuone.SyncDaemon"
- DBUS_IFACE_CONFIG_NAME = DBUS_IFACE_NAME + ".Config"
-
- # Why thank you GTK+ for enforcing style-set and breaking API
- RCSTYLE = """
- style 'dialogs' {
- GtkDialog::action-area-border = 12
- GtkDialog::button-spacing = 6
- GtkDialog::content-area-border = 0
- }
- widget_class '*Dialog*' style 'dialogs'
- """
-
- CONF_FILE = os.path.join(xdg_config_home, "ubuntuone", "ubuntuone-client.conf")
-
- def dbus_async(*args):
- """Simple handler to make dbus do stuff async."""
- pass
-
-
- class AppletConfigDialog(gtk.Dialog):
- """Preferences dialog."""
-
- def __init__(self, config=None, *args, **kw):
- """Initializes our config dialog."""
- super(AppletConfigDialog, self).__init__(*args, **kw)
- self.set_title(_("Ubuntu One Preferences"))
- self.set_has_separator(False)
- self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
- self.set_default_response(gtk.RESPONSE_CLOSE)
- self.set_icon_name("ubuntuone-client")
-
- self.connect("close", self.__handle_response, gtk.RESPONSE_CLOSE)
- self.connect("response", self.__handle_response)
-
- self.config = config
-
- self.bw_enabled = False
- self.up_limit = 2097152
- self.dn_limit = 2097152
-
- self.__bus = dbus.SessionBus()
-
- try:
- client = self.__bus.get_object(DBUS_IFACE_NAME, "/config",
- follow_name_owner_changes=True)
- iface = dbus.Interface(client, DBUS_IFACE_CONFIG_NAME)
- iface.get_throttling_limits(
- reply_handler=self.__got_limits,
- error_handler=self.__dbus_error)
- iface.bandwidth_throttling_enabled(
- reply_handler=self.__got_enabled,
- error_handler=self.__dbus_error)
- except DBusException, e:
- self.__dbus_error(e)
-
- # Timeout ID to avoid spamming DBus from spinbutton changes
- self.__update_id = 0
-
- self.load_config()
-
- self.__construct()
-
- def load_config(self):
- """Load the configuration, and initilize if empty."""
- if not os.path.isdir(os.path.dirname(CONF_FILE)):
- os.makedirs(os.path.dirname(CONF_FILE))
-
- self.config = ConfigParser()
- self.config.read(CONF_FILE)
-
- if not self.config.has_section("ubuntuone"):
- self.config.add_section("ubuntuone")
-
- if not self.config.has_option("ubuntuone", "show_applet"):
- self.config.set("ubuntuone", "show_applet", "1")
-
- if not self.config.has_option("ubuntuone", "connect"):
- self.config.set("ubuntuone", "connect", "0")
-
- if not self.config.has_option("ubuntuone", "connected"):
- self.config.set("ubuntuone", "connected", "False")
-
- if not os.path.exists(CONF_FILE):
- self.save_config()
-
- def save_config(self):
- """Write the configuration back to a file."""
- with open(CONF_FILE, "w+b") as f:
- self.config.write(f)
-
- def quit(self):
- """Exit the main loop."""
- gtk.main_quit()
-
- def __dbus_error(self, error):
- """Error getting throttling config."""
- print repr(error)
-
- def __got_limits(self, limits):
- """Got the throttling limits."""
- self.up_limit = int(limits['upload'])
- self.dn_limit = int(limits['download'])
-
- def __got_enabled(self, enabled):
- """Got the throttling enabled config."""
- self.bw_enabled = bool(enabled)
-
- def __update_bw_settings(self):
- """Update the bandwidth throttling config in syncdaemon."""
- self.bw_enabled = self.limit_check.get_active()
- self.up_limit = self.up_spin.get_value_as_int() * 1024
- self.dn_limit = self.dn_spin.get_value_as_int() * 1024
-
- try:
- client = self.__bus.get_object(DBUS_IFACE_NAME, "/config",
- follow_name_owner_changes=True)
- iface = dbus.Interface(client, DBUS_IFACE_CONFIG_NAME)
- iface.set_throttling_limits(self.dn_limit, self.up_limit,
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- if self.bw_enabled:
- iface.enable_bandwidth_throttling(
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- else:
- iface.disable_bandwidth_throttling(
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- except DBusException, e:
- self.__dbus_error(e)
-
- def __handle_response(self, dialog, response):
- """Handle the dialog's response."""
- self.hide()
- self.config.set("ubuntuone", "show_applet",
- self.show_menu.get_active())
- self.config.set("ubuntuone", "connect",
- self.conn_menu.get_active())
-
- self.__update_bw_settings()
- self.save_config()
- gtk.main_quit()
-
- def __show_menu_changed(self, menu, data=None):
- """Update the config for showing the applet."""
- value = menu.get_active()
- self.config.set("ubuntuone", "show_applet", str(value))
- try:
- client = self.__bus.get_object(APPLET_IFACE_NAME, "/config",
- follow_name_owner_changes=True)
- iface = dbus.Interface(client, APPLET_IFACE_CONFIG_NAME)
- iface.set_visibility_config(value, reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- except DBusException, e:
- self.__dbus_error(e)
-
- def __conn_menu_changed(self, menu, data=None):
- """Update the config for showing the applet."""
- value = menu.get_active()
- self.config.set("ubuntuone", "connect", str(value))
- try:
- client = self.__bus.get_object(APPLET_IFACE_NAME, "/config",
- follow_name_owner_changes=True)
- iface = dbus.Interface(client, APPLET_IFACE_CONFIG_NAME)
- iface.set_connection_config(value, reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- except DBusException, e:
- self.__dbus_error(e)
-
- def __bw_limit_toggled(self, button, data=None):
- """Toggle the bw limit panel."""
- self.bw_enabled = self.limit_check.get_active()
- self.bw_table.set_sensitive(self.bw_enabled)
- try:
- client = self.__bus.get_object(DBUS_IFACE_NAME, "/config",
- follow_name_owner_changes=True)
- iface = dbus.Interface(client, DBUS_IFACE_CONFIG_NAME)
- iface.set_throttling_limits(self.dn_limit, self.up_limit,
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- if self.bw_enabled:
- iface.enable_bandwidth_throttling(
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- else:
- iface.disable_bandwidth_throttling(
- reply_handler=dbus_async,
- error_handler=self.__dbus_error)
- except DBusException, e:
- self.__dbus_error(e)
-
- def __spinner_changed(self, button, data=None):
- """Remove timeout and add anew."""
- if self.__update_id != 0:
- gobject.source_remove(self.__update_id)
-
- self.__update_id = gobject.timeout_add_seconds(
- 1, self.__update_bw_settings)
-
- def __construct(self):
- """Construct the dialog's layout."""
- area = self.get_content_area()
-
- vbox = gtk.VBox(spacing=12)
- vbox.set_border_width(12)
- area.add(vbox)
- vbox.show()
-
- # Put the first set of options in a table.
- table = gtk.Table(rows=2, columns=2)
- table.set_row_spacings(12)
- table.set_col_spacings(6)
- vbox.add(table)
- table.show()
-
- label = gtk.Label(_("_Show icon:"))
- label.set_use_underline(True)
- label.set_alignment(0, 0.5)
- table.attach(label, 0, 1, 0, 1)
- label.show()
-
- self.show_menu = gtk.combo_box_new_text()
- self.show_menu.connect("changed", self.__show_menu_changed)
- label.set_mnemonic_widget(self.show_menu)
- self.show_menu.append_text(_("Always"))
- self.show_menu.append_text(_("When updating"))
- self.show_menu.append_text(_("Never"))
- self.show_menu.set_active(self.config.getint("ubuntuone",
- "show_applet"))
- table.attach(self.show_menu, 1, 2, 0, 1)
- self.show_menu.show()
-
- label = gtk.Label(_("Connect on start:"))
- label.set_use_underline(True)
- label.set_alignment(0, 0.5)
- table.attach(label, 0, 1, 1, 2)
- label.show()
-
- self.conn_menu = gtk.combo_box_new_text()
- self.conn_menu.connect("changed", self.__conn_menu_changed)
- label.set_mnemonic_widget(self.conn_menu)
- self.conn_menu.append_text(_("Automatically"))
- self.conn_menu.append_text(_("Remember last"))
- self.conn_menu.append_text(_("Never"))
- self.conn_menu.set_active(self.config.getint("ubuntuone",
- "connect"))
- table.attach(self.conn_menu, 1, 2, 1, 2)
- self.conn_menu.show()
-
- # Bandwidth limiting
- self.limit_check = gtk.CheckButton(_("_Limit Bandwidth Usage"))
- self.limit_check.connect("toggled", self.__bw_limit_toggled)
- vbox.add(self.limit_check)
- self.limit_check.show()
-
- hbox = gtk.HBox(spacing=12)
- vbox.add(hbox)
- hbox.show()
-
- label = gtk.Label()
- hbox.add(label)
- label.show()
-
- # Now put the bw limit bits in a table too
- self.bw_table = gtk.Table(rows=2, columns=2)
- self.bw_table.set_row_spacings(6)
- self.bw_table.set_col_spacings(6)
- self.bw_table.set_sensitive(False)
- hbox.add(self.bw_table)
- self.bw_table.show()
-
- # Upload speed
- label = gtk.Label(_("Maximum _upload speed (KB/s):"))
- label.set_use_underline(True)
- label.set_alignment(0, 0.5)
- self.bw_table.attach(label, 0, 1, 0, 1)
- label.show()
-
- adjustment = gtk.Adjustment(value=2048.0, lower=0.0, upper=4096.0,
- step_incr=64.0, page_incr=128.0)
- self.up_spin = gtk.SpinButton(adjustment)
- self.up_spin.connect("value-changed", self.__spinner_changed)
- label.set_mnemonic_widget(self.up_spin)
- self.bw_table.attach(self.up_spin, 1, 2, 0, 1)
- self.up_spin.show()
-
- # Download speed
- label = gtk.Label(_("Maximum _download speed (KB/s):"))
- label.set_use_underline(True)
- label.set_alignment(0, 0.5)
- self.bw_table.attach(label, 0, 1, 1, 2)
- label.show()
- adjustment = gtk.Adjustment(value=2048.0, lower=0.0, upper=4096.0,
- step_incr=64.0, page_incr=128.0)
- self.dn_spin = gtk.SpinButton(adjustment)
- self.dn_spin.connect("value-changed", self.__spinner_changed)
- label.set_mnemonic_widget(self.dn_spin)
- self.bw_table.attach(self.dn_spin, 1, 2, 1, 2)
- self.dn_spin.show()
-
-
- if __name__ == "__main__":
- gettext.bindtextdomain(clientdefs.GETTEXT_PACKAGE, clientdefs.LOCALEDIR)
- gettext.textdomain(clientdefs.GETTEXT_PACKAGE)
-
- gtk.rc_parse_string(RCSTYLE)
-
- try:
- dialog = AppletConfigDialog()
- dialog.show()
- gtk.main()
- except KeyboardInterrupt:
- pass
-